<?php

namespace App\Services;

use App\Constants\ErrorCode;
use App\Exception\BusinessException;
use App\Model\Sign;
use App\Services\Dao\MeetingDao;
use App\Services\Dao\SignDao;
use App\Services\Formatter\MeetingFormatter;
use Carbon\Carbon;
use Hyperf\Database\Model\Builder;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Utils\Codec\Json;

class SignService
{
    /**
     * @Inject
     * @var MeetingDao
     */
    protected $meetingDao;

    /**
     * @Inject
     * @var SignDao
     */
    protected $signDao;

    /**
     * @Inject
     * @var MeetingFormatter
     */
    protected $meetingFormatter;

    public function sign(int $userId, array $params): bool
    {
        $meetingId = $params['meetingId'];
        $meeting = $this->meetingDao->first($meetingId, true);
        $now = Carbon::now();
        $type = $params['type'];
        if (!$meeting->isAllowSign($type, $now)) {
            throw new BusinessException(ErrorCode::SIGN_TIME_INVALID, ErrorCode::getMessage(ErrorCode::SIGN_TIME_INVALID));
        }
        $model = $this->signDao->first($meetingId, $userId, $type);
        if (empty($model)) {
            $model = new Sign();
            $model->meeting_id = $meetingId;
            $model->user_id = $userId;
            $model->type = $type;
        }
        $model->last_sign_at = $now;
        $model->username = $params['username'];
        $model->phone = $params['phone'] ?? '';
        $model->wechat_code = $params['wechatCode'] ?? '';
        $model->fields = Json::encode((object)($params['fields'] ?? ''));

        return $model->save();
    }

    /**
     * @param int $userId
     * @return array
     */
    public function takePartIn(int $userId): array
    {
        $sginInfo = $this->signDao->findTakePartIn($userId);
        if (empty($sginInfo)) {
            return [];
        }
        $mids = array_column($sginInfo->toArray(), "meeting_id");
        $info = $this->meetingDao->findMeetingByIds($mids);
        if (empty($info)) {
            return [];
        }
        return $this->meetingFormatter->formatList($info);
    }


}